package com.jh.paymentchannel.pojo.profit;

import com.google.common.base.Charsets;
import com.jh.paymentchannel.util.Util;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.Collections;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


/**
 * @author Fuchun
 * @since 1.0
 */
@Component("pmtProfitRateProvider")
public class DefaultPmtProfitRateProvider implements PmtProfitRateProvider, InitializingBean {

    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final RestTemplate restTemplate;
    private final ScheduledExecutorService executorService;

    private volatile PmtProfitRate profitRate = PmtProfitRate.getDefaultProfitRate();
    private volatile String profitRateJson;
    private volatile boolean isDefault = true;


    @Autowired
    public DefaultPmtProfitRateProvider(
            @Qualifier("restOperations") RestTemplate restTemplate,
            ScheduledExecutorService executorService) {
        this.restTemplate = restTemplate;
        this.executorService = executorService;
    }

    @NotNull
    @Override
    public PmtProfitRate getProfitRate() {
        resolveProfitRate(false);
        return profitRate;
    }

    @NotNull
    @Override
    public String getProfitRateJson() {
        resolveProfitRate(false);
        return profitRateJson;
    }

    private HttpEntity<Object> requestEntity() {
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
        headers.setAcceptCharset(Collections.singletonList(Charsets.UTF_8));
        return new HttpEntity<>(headers);
    }

    private void resolveProfitRate(boolean forced) {
        if (!isDefault && !forced) return;
        synchronized (this) {
            PmtProfitRate targetRate = requestAndGetProfitRate();
            if (targetRate == null) {
                profitRate = PmtProfitRate.getDefaultProfitRate();
                profitRateJson = profitRate.toJson();
                isDefault = true;
            } else {
                profitRate = targetRate;
                profitRateJson = profitRate.toJson();
                isDefault = false;
            }
        }
    }

    private PmtProfitRate requestAndGetProfitRate() {
        ResponseEntity<String> response;
        try {
//            URI uri = util.getServiceUrl("user", "");
//            String url = uri + "/v1.0/user/third_pay/rate/brand";
//            response = restTemplate.postForEntity(url, requestEntity(), String.class);
            response = restTemplate.postForEntity(
                    "http://user/v1.0/user/third_pay/rate/brand", requestEntity(), String.class);
        } catch (Exception ex) {
            logger.error("Pull `/v1.0/user/third_pay/rate/brand` to get PmtProfitRate fail: {}", ex.getMessage());
            return null;
        }
        PmtProfitRate ppr = null;
        if (response.getStatusCode().is2xxSuccessful()) {
            String jsonData = response.getBody();
            try {
                ppr = PmtProfitRate.fromJson(jsonData);
            } catch (Exception ex) {
                return null;
            }
        }
        return ppr;
    }

    @Override
    public void afterPropertiesSet() {
        // 每小时请求更新
        executorService.scheduleAtFixedRate(() -> resolveProfitRate(true), 0, 1, TimeUnit.HOURS);
    }
}
